home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2002 November / SGI Freeware 2002 November - Disc 3.iso / dist / fw_qt3.idb / usr / freeware / Qt / examples / themes / metal.cpp.z / metal.cpp
Encoding:
C/C++ Source or Header  |  2002-04-08  |  12.1 KB  |  488 lines

  1. /****************************************************************************
  2. ** $Id:  qt/metal.cpp   3.0.3   edited Dec 4 19:47 $
  3. **
  4. ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
  5. **
  6. ** This file is part of an example program for Qt.  This example
  7. ** program may be used, distributed and modified without limitation.
  8. **
  9. *****************************************************************************/
  10.  
  11. #include "metal.h"
  12.  
  13. #ifndef QT_NO_STYLE_WINDOWS
  14.  
  15. #include "qapplication.h"
  16. #include "qcombobox.h"
  17. #include "qpainter.h"
  18. #include "qdrawutil.h" // for now
  19. #include "qpixmap.h" // for now
  20. #include "qpalette.h" // for now
  21. #include "qwidget.h"
  22. #include "qlabel.h"
  23. #include "qimage.h"
  24. #include "qpushbutton.h"
  25. #include "qwidget.h"
  26. #include "qrangecontrol.h"
  27. #include "qscrollbar.h"
  28. #include "qslider.h"
  29. #include <limits.h>
  30.  
  31.  
  32. /////////////////////////////////////////////////////////
  33. #include "stonedark.xpm"
  34. #include "stone1.xpm"
  35. #include "marble.xpm"
  36. ///////////////////////////////////////////////////////
  37.  
  38.  
  39.  
  40. MetalStyle::MetalStyle() : QWindowsStyle() { }
  41.  
  42. /*!
  43.   Reimplementation from QStyle
  44.  */
  45. void MetalStyle::polish( QApplication *app)
  46. {
  47.     oldPalette = app->palette();
  48.  
  49.     // we simply create a nice QColorGroup with a couple of fancy
  50.     // pixmaps here and apply to it all widgets
  51.  
  52.     QFont f("times", app->font().pointSize() );
  53.     f.setBold( TRUE );
  54.     f.setItalic( TRUE );
  55.     app->setFont( f, TRUE, "QMenuBar");
  56.     app->setFont( f, TRUE, "QPopupMenu");
  57.  
  58.  
  59.  
  60.     //    QPixmap button( stonedark_xpm );
  61.  
  62.     QColor gold("#B9B9A5A54040"); //same as topgrad below
  63.     QPixmap button( 1, 1 ); button.fill( gold );
  64.  
  65.     QPixmap background(marble_xpm);
  66.     QPixmap dark( 1, 1 ); dark.fill( red.dark() );
  67.     QPixmap mid( stone1_xpm );
  68.     QPixmap light( stone1_xpm );//1, 1 ); light.fill( green );
  69.  
  70.     QPalette op = app->palette();
  71.  
  72.     QColor backCol( 227,227,227 );
  73.  
  74.     // QPalette op(white);
  75.     QColorGroup active (op.active().foreground(),
  76.              QBrush(op.active().button(),button),
  77.              QBrush(op.active().light(), light),
  78.              QBrush(op.active().dark(), dark),
  79.              QBrush(op.active().mid(), mid),
  80.              op.active().text(),
  81.              Qt::white,
  82.              op.active().base(),//             QColor(236,182,120),
  83.              QBrush(backCol, background)
  84.              );
  85.     active.setColor( QColorGroup::ButtonText,  Qt::white  );
  86.     active.setColor( QColorGroup::Shadow,  Qt::black  );
  87.     QColorGroup disabled (op.disabled().foreground(),
  88.              QBrush(op.disabled().button(),button),
  89.              QBrush(op.disabled().light(), light),
  90.              op.disabled().dark(),
  91.              QBrush(op.disabled().mid(), mid),
  92.              op.disabled().text(),
  93.              Qt::white,
  94.              op.disabled().base(),//             QColor(236,182,120),
  95.              QBrush(backCol, background)
  96.              );
  97.  
  98.     QPalette newPalette( active, disabled, active );
  99.     app->setPalette( newPalette, TRUE );
  100. }
  101.  
  102. /*!
  103.   Reimplementation from QStyle
  104.  */
  105. void MetalStyle::unPolish( QApplication *app)
  106. {
  107.     app->setPalette(oldPalette, TRUE);
  108.     app->setFont( app->font(), TRUE );
  109. }
  110.  
  111. /*!
  112.   Reimplementation from QStyle
  113.  */
  114. void MetalStyle::polish( QWidget* w)
  115. {
  116.  
  117.    // the polish function sets some widgets to transparent mode and
  118.     // some to translate background mode in order to get the full
  119.     // benefit from the nice pixmaps in the color group.
  120.  
  121.     if (w->inherits("QPushButton")){
  122.     w->setBackgroundMode( QWidget::NoBackground );
  123.     return;
  124.     }
  125.  
  126.     if ( !w->isTopLevel() ) {
  127.     if ( w->backgroundPixmap() )
  128.         w->setBackgroundOrigin( QWidget::WindowOrigin );
  129.     }
  130. }
  131.  
  132. void MetalStyle::unPolish( QWidget* w)
  133. {
  134.  
  135.    // the polish function sets some widgets to transparent mode and
  136.     // some to translate background mode in order to get the full
  137.     // benefit from the nice pixmaps in the color group.
  138.  
  139.     if (w->inherits("QPushButton")){
  140.     w->setBackgroundMode( QWidget::PaletteButton );
  141.     return;
  142.     }
  143.     if ( !w->isTopLevel() ) {
  144.     if ( w->backgroundPixmap() )
  145.         w->setBackgroundOrigin( QWidget::WidgetOrigin );
  146.     }
  147.  
  148. }
  149.  
  150. void MetalStyle::drawPrimitive( PrimitiveElement pe,
  151.                 QPainter *p,
  152.                 const QRect &r,
  153.                 const QColorGroup &cg,
  154.                 SFlags flags, const QStyleOption& opt ) const
  155. {
  156.     switch( pe ) {
  157.     case PE_HeaderSection:
  158.     if ( flags & Style_Sunken )
  159.         flags ^= Style_Sunken | Style_Raised;
  160.     // fall through
  161.     case PE_ButtonBevel:
  162.     case PE_ButtonCommand:
  163.         drawMetalButton( p, r.x(), r.y(), r.width(), r.height(),
  164.                  (flags & (Style_Sunken|Style_On|Style_Down)),
  165.                  TRUE, !(flags & Style_Raised) );
  166.         break;
  167.     case PE_PanelMenuBar:
  168.     drawMetalFrame( p, r.x(), r.y(), r.width(), r.height() );
  169.     break;
  170.     case PE_ScrollBarAddLine:    
  171.     drawMetalButton( p, r.x(), r.y(), r.width(), r.height(),
  172.              flags & Style_Down, !( flags & Style_Horizontal ) );
  173.     drawPrimitive( (flags & Style_Horizontal) ? PE_ArrowRight :PE_ArrowDown,
  174.                p, r, cg, flags, opt );
  175.     break;
  176.     case PE_ScrollBarSubLine:
  177.     drawMetalButton( p, r.x(), r.y(), r.width(), r.height(),
  178.              flags & Style_Down, !( flags & Style_Horizontal ) );
  179.     drawPrimitive( (flags & Style_Horizontal) ? PE_ArrowLeft : PE_ArrowUp,
  180.                p, r, cg, flags, opt );
  181.     break;
  182.  
  183.     
  184.     case PE_ScrollBarSlider:
  185.     drawMetalButton( p, r.x(), r.y(), r.width(), r.height(), FALSE,
  186.              flags & Style_Horizontal );
  187.     break;
  188.     default:
  189.     QWindowsStyle::drawPrimitive( pe, p, r, cg, flags, opt );
  190.     break;
  191.     }
  192. }
  193.  
  194. void MetalStyle::drawControl( ControlElement element,
  195.                   QPainter *p,
  196.                   const QWidget *widget,
  197.                   const QRect &r,
  198.                   const QColorGroup &cg,
  199.                   SFlags how,
  200.                   const QStyleOption& opt ) const
  201. {
  202.     switch( element ) {
  203.     case CE_PushButton:
  204.     {
  205.         const QPushButton *btn;
  206.         btn = (const QPushButton*)widget;
  207.         int x1, y1, x2, y2;
  208.     
  209.         r.coords( &x1, &y1, &x2, &y2 );
  210.     
  211.         p->setPen( cg.foreground() );
  212.         p->setBrush( QBrush(cg.button(), NoBrush) );
  213.  
  214.     
  215.         QBrush fill;
  216.         if ( btn->isDown() )
  217.         fill = cg.brush( QColorGroup::Mid );
  218.         else if ( btn->isOn() )
  219.         fill = QBrush( cg.mid(), Dense4Pattern );
  220.         else
  221.         fill = cg.brush( QColorGroup::Button );
  222.     
  223.         if ( btn->isDefault() ) {
  224.         QPointArray a;
  225.         a.setPoints( 9,
  226.                  x1, y1, x2, y1, x2, y2, x1, y2, x1, y1+1,
  227.                  x2-1, y1+1, x2-1, y2-1, x1+1, y2-1, x1+1, y1+1 );
  228.         p->setPen( Qt::black );
  229.         p->drawPolyline( a );
  230.         x1 += 2;
  231.         y1 += 2;
  232.         x2 -= 2;
  233.         y2 -= 2;
  234.         }
  235.         SFlags flags = Style_Default;
  236.         if ( btn->isOn() )
  237.         flags |= Style_On;
  238.         if ( btn->isDown() )
  239.         flags |= Style_Down;
  240.         if ( !btn->isFlat() && !btn->isDown() )
  241.         flags |= Style_Raised;
  242.         drawPrimitive( PE_ButtonCommand, p,
  243.                QRect( x1, y1, x2 - x1 + 1, y2 - y1 + 1),
  244.                cg, flags, opt );
  245.     
  246.         if ( btn->isMenuButton() ) {
  247.         flags = Style_Default;
  248.         if ( btn->isEnabled() )
  249.             flags |= Style_Enabled;
  250.         
  251.         int dx = ( y1 - y2 - 4 ) / 3;
  252.         drawPrimitive( PE_ArrowDown, p,
  253.                    QRect(x2 - dx, dx, y1, y2 - y1),
  254.                    cg, flags, opt );
  255.         }
  256.         if ( p->brush().style() != NoBrush )
  257.         p->setBrush( NoBrush );
  258.         break;
  259.     }
  260.     case CE_PushButtonLabel:
  261.     {
  262.         const QPushButton *btn;
  263.         btn = (const QPushButton*)widget;
  264.         int x, y, w, h;
  265.         r.rect( &x, &y, &w, &h );
  266.     
  267.         int x1, y1, x2, y2;
  268.         r.coords( &x1, &y1, &x2, &y2 );
  269.         int dx = 0;
  270.         int dy = 0;
  271.         if ( btn->isMenuButton() )
  272.         dx = ( y2 - y1 ) / 3;
  273.         if ( btn->isOn() || btn->isDown() ) {
  274.         dx--;
  275.         dy--;
  276.         }
  277.         if ( dx || dy )
  278.         p->translate( dx, dy );
  279.         x += 2;
  280.         y += 2;
  281.         w -= 4;
  282.         h -= 4;
  283.         drawItem( p, QRect( x, y, w, h ),
  284.               AlignCenter|ShowPrefix,
  285.               cg, btn->isEnabled(),
  286.               btn->pixmap(), btn->text(), -1,
  287.               (btn->isDown() || btn->isOn())? &cg.brightText() : &cg.buttonText() );
  288.         if ( dx || dy )
  289.         p->translate( -dx, -dy );
  290.         break;
  291.     }
  292.     default:
  293.     QWindowsStyle::drawControl( element, p, widget, r, cg, how, opt );
  294.     break;
  295.     }
  296. }
  297. void MetalStyle::drawComplexControl( ComplexControl cc,
  298.                      QPainter *p,
  299.                      const QWidget *widget,
  300.                      const QRect &r,
  301.                      const QColorGroup &cg,
  302.                      SFlags how,
  303.                      SCFlags sub,
  304.                      SCFlags subActive,
  305.                      const QStyleOption& opt ) const
  306. {
  307.     switch ( cc ) {
  308.     case CC_Slider:
  309.     {
  310.         const QSlider *slider = ( const QSlider* ) widget;
  311.         QRect handle = querySubControlMetrics( CC_Slider, widget,
  312.                            SC_SliderHandle, opt);
  313.         if ( sub & SC_SliderGroove )
  314.         QWindowsStyle::drawComplexControl( cc, p, widget, r, cg, how,
  315.                            SC_SliderGroove, subActive, opt );
  316.         if ( (sub & SC_SliderHandle) && handle.isValid() )
  317.         drawMetalButton( p, handle.x(), handle.y(), handle.width(),
  318.                  handle.height(), FALSE,
  319.                  slider->orientation() == QSlider::Horizontal);
  320.         break;
  321.     }
  322.     case CC_ComboBox:
  323.     {
  324.         // not exactly correct...
  325.         const QComboBox *cmb = ( const QComboBox* ) widget;
  326.     
  327.         qDrawWinPanel( p, r.x(), r.y(), r.width(), r.height(), cg, TRUE,
  328.                cmb->isEnabled() ? &cg.brush( QColorGroup::Base ) :
  329.                                   &cg.brush( QColorGroup::Background ) );
  330.         drawMetalButton( p, r.x() + r.width() - 2 - 16, r.y() + 2, 16, r.height() - 4,
  331.                  how & Style_Sunken, TRUE );
  332.         drawPrimitive( PE_ArrowDown, p,
  333.                QRect( r.x() + r.width() - 2 - 16 + 2,
  334.                   r.y() + 2 + 2, 16 - 4, r.height() - 4 -4 ),
  335.                cg,
  336.                cmb->isEnabled() ? Style_Enabled : Style_Default,
  337.                opt );
  338.         break;
  339.     }
  340.     default:
  341.     QWindowsStyle::drawComplexControl( cc, p, widget, r, cg, how, sub, subActive,
  342.                        opt );
  343.     break;
  344.     }
  345. }
  346.         
  347.  
  348. /*!
  349.   Draw a metallic button, sunken if \a sunken is TRUE, horizontal if
  350.   /a horz is TRUE.
  351. */
  352.  
  353. void MetalStyle::drawMetalButton( QPainter *p, int x, int y, int w, int h,
  354.                   bool sunken, bool horz, bool flat  ) const
  355. {
  356.  
  357.     drawMetalFrame( p, x, y, w, h );
  358.     drawMetalGradient( p, x, y, w, h, sunken, horz, flat );
  359. }
  360.  
  361.  
  362.  
  363.  
  364. void MetalStyle::drawMetalFrame( QPainter *p, int x, int y, int w, int h ) const
  365. {
  366.     QColor top1("#878769691515");
  367.     QColor top2("#C6C6B4B44949");
  368.  
  369.     QColor bot2("#70705B5B1414");
  370.     QColor bot1("#56564A4A0E0E"); //first from the bottom
  371.  
  372.  
  373.     int x2 = x + w - 1;
  374.     int y2 = y + h - 1;
  375.  
  376.     //frame:
  377.  
  378.     p->setPen( top1 );
  379.     p->drawLine( x, y2, x, y );
  380.     p->drawLine( x, y, x2-1, y );
  381.     p->setPen( top2 );
  382.     p->drawLine( x+1, y2 -1, x+1, y+1 );
  383.     p->drawLine( x+1, y+1 , x2-2, y+1 );
  384.  
  385.     p->setPen( bot1 );
  386.     p->drawLine( x+1, y2, x2, y2 );
  387.     p->drawLine( x2, y2, x2, y );
  388.     p->setPen( bot2 );
  389.     p->drawLine( x+1, y2-1, x2-1, y2-1 );
  390.     p->drawLine( x2-1, y2-1, x2-1, y+1 );
  391.  
  392.  
  393. }
  394.  
  395.  
  396. void MetalStyle::drawMetalGradient( QPainter *p, int x, int y, int w, int h,
  397.                     bool sunken, bool horz, bool flat  ) const
  398.  
  399. {
  400.     QColor highlight("#E8E8DDDD6565");
  401.     QColor subh1("#CECEBDBD5151");
  402.     QColor subh2("#BFBFACAC4545");
  403.  
  404.     QColor topgrad("#B9B9A5A54040");
  405.     QColor botgrad("#89896C6C1A1A");
  406.  
  407.  
  408.  
  409.     if ( flat && !sunken ) {
  410.         p->fillRect( x + 2, y + 2, w - 4,h -4, topgrad );
  411.     } else {
  412.     // highlight:
  413.     int i = 0;
  414.     int x1 = x + 2;
  415.     int y1 = y + 2;
  416.     int x2 = x + w - 1;
  417.     int y2 = y + h - 1;
  418.     if ( horz )
  419.         x2 = x2 - 2;
  420.     else
  421.         y2 = y2 - 2;
  422.     
  423. #define DRAWLINE if (horz) \
  424.                     p->drawLine( x1, y1+i, x2, y1+i ); \
  425.          else \
  426.                     p->drawLine( x1+i, y1, x1+i, y2 ); \
  427.                  i++;
  428.  
  429.     if ( !sunken ) {
  430.         p->setPen( highlight );
  431.         DRAWLINE;
  432.         DRAWLINE;
  433.         p->setPen( subh1 );
  434.         DRAWLINE;
  435.         p->setPen( subh2 );
  436.         DRAWLINE;
  437.     }
  438.     // gradient:
  439.     int ng = (horz ? h : w) - 8; // how many lines for the gradient?
  440.     
  441.     int h1, h2, s1, s2, v1, v2;
  442.     if ( !sunken ) {
  443.         topgrad.hsv( &h1, &s1, &v1 );
  444.         botgrad.hsv( &h2, &s2, &v2 );
  445.     } else {
  446.         botgrad.hsv( &h1, &s1, &v1 );
  447.         topgrad.hsv( &h2, &s2, &v2 );
  448.     }
  449.     
  450.     if ( ng > 1 ) {    
  451.         for ( int j =0; j < ng; j++ ) {
  452.         p->setPen( QColor( h1 + ((h2-h1)*j)/(ng-1),
  453.                    s1 + ((s2-s1)*j)/(ng-1),
  454.                    v1 + ((v2-v1)*j)/(ng-1),  QColor::Hsv ) );
  455.         DRAWLINE;
  456.         }
  457.     } else if ( ng == 1 ) {
  458.         p->setPen( QColor((h1+h2)/2, (s1+s2)/2, (v1+v2)/2, QColor::Hsv) );
  459.         DRAWLINE;
  460.     }
  461.     if ( sunken ) {
  462.         p->setPen( subh2 );
  463.         DRAWLINE;
  464.         
  465.         p->setPen( subh1 );
  466.         DRAWLINE;
  467.         
  468.         p->setPen( highlight );
  469.         DRAWLINE;
  470.         DRAWLINE;
  471.     }
  472.     }    
  473. }
  474.  
  475.  
  476.  
  477. int MetalStyle::pixelMetric( PixelMetric metric, const QWidget *w ) const
  478. {
  479.     switch ( metric ) {
  480.     case PM_MenuBarFrameWidth:
  481.     return 2;
  482.     default:
  483.     return QWindowsStyle::pixelMetric( metric, w );
  484.     }
  485. }
  486.  
  487. #endif
  488.